package yclient

import (
	"NicePay/utils"
	"time"
	"github.com/parnurzeal/gorequest"
	"encoding/json"
)

type YClient struct {
	ClientId     string
	ClientSecret string
	KdtId        int
	AccessToken  string
	ExpireAt     time.Time
}

type msgMap map[string]interface{}

var yClient *YClient

func Obtain() YClient {
	if yClient == nil {
		yzConfig := utils.GetConfig().YouZan
		yClient = &YClient{
			ClientId:     yzConfig.ClientId,
			ClientSecret: yzConfig.ClientSecret,
			KdtId:        yzConfig.KdtId,
		}
	}
	yClient.updateToken()
	return *yClient
}

func (y *YClient) updateToken() {
	if time.Now().Before(y.ExpireAt) {
		return
	}
	_, body, errs := gorequest.New().Post("https://open.youzan.com/oauth/token").
		Type("multipart").Send(msgMap{
		"client_id":     yClient.ClientId,
		"client_secret": yClient.ClientSecret,
		"grant_type":    "silent",
		"kdt_id":        yClient.KdtId,
	}).End()
	if len(errs) != 0 {
		panic(errs)
	}
	tokenResp := new(TokenResp)
	json.Unmarshal([]byte(body), tokenResp)
	if tokenResp.ExpiresIn != 0 {
		y.AccessToken = tokenResp.AccessToken
		y.ExpireAt = time.Now().Add(5 * 24 * time.Hour)
	}
	//log.Println(tokenResp)
}

func (y YClient) GetQrCode(name string, price int) (string, string) {
	url := "https://open.youzan.com/api/oauthentry/youzan.pay.qrcode/3.0.0/create?access_token=" + y.AccessToken
	_, body, errs := gorequest.New().Post(url).Type("multipart").
		Send(msgMap{
		"qr_name":  name,
		"qr_price": price,
		"qr_type":  "QR_TYPE_DYNAMIC",
	}).End()
	if len(errs) != 0 {
		panic(errs)
	}
	qrResp := new(QrResp)
	json.Unmarshal([]byte(body), qrResp)
	return qrResp.Response.QrId, qrResp.Response.QrCode
}

func (y YClient) FetchQrId(tid string) Trade {
	url := "https://open.youzan.com/api/oauthentry/youzan.trade/3.0.0/get?access_token=" + y.AccessToken
	_, body, errs := gorequest.New().Post(url).Type("multipart").
		Send(msgMap{
		"tid": tid,
	}).End()
	if len(errs) != 0 {
		panic(errs)
	}
	//log.Println(body)
	tradeResp := new(TradeResp)
	json.Unmarshal([]byte(body), tradeResp)
	return tradeResp.Response.Trade
}
